package maker

import (
	"errors"
	payloadPkg "gitee.com/nanakura/gin-middleware-paseto/payload"
	"github.com/o1egl/paseto"
	"time"
)

type Maker interface {
	CreateToken(username string, duration time.Duration) (string, error)
	VerifyToken(token string) (*payloadPkg.Payload, error)
}

type PasetoMaker struct {
	paseto       paseto.V2
	symmetricKey []byte
}

func (p *PasetoMaker) CreateToken(username string, duration time.Duration) (string, error) {
	payload, err := payloadPkg.NewPayload(username, duration)
	if err != nil {
		return "", nil
	}
	return p.paseto.Encrypt(p.symmetricKey, payload, nil)
}

func (p *PasetoMaker) VerifyToken(token string) (*payloadPkg.Payload, error) {
	payload := &payloadPkg.Payload{}
	err := p.paseto.Decrypt(token, p.symmetricKey, payload, nil)
	if err != nil {
		return nil, payloadPkg.ErrorInvalidToken
	}
	err = payload.Valid()
	if err != nil {
		return nil, payloadPkg.ErrorInvalidToken
	}
	return payload, nil
}

func NewPasetoMaker(symmetricKey string) (Maker, error) {
	key := []byte(symmetricKey)
	if len(key) < payloadPkg.MinLengthSecretKey {
		return nil, errors.New("Invalid symmetric key length (Must be 32 bytes)")
	}
	maker := &PasetoMaker{
		paseto:       *paseto.NewV2(),
		symmetricKey: key,
	}
	return maker, nil
}
